﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Encog.ML.Data;
using Encog.ML.Data.Market;
using Encog.ML.Data.Market.Loader;
using Encog.Neural.NeuralData;
using Encog.Util;
using Encog.Util.Simple;
using Encog.Neural.Networks;
using Encog.Neural.Data;
using Microsoft.Win32;
using Encog.Persist;
using System.IO;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using Encog.ML.Data.Basic;

namespace IntObl
{
    public partial class Form1 : Form
    {
        public Utils Util { get; set; }

       // nauczana sieć
        public BasicNetwork Network { get; set; }


        // dane treningowe
        public IMLDataSet Training { get; set; }

        public DateTime StartDate { get; set; }

        public DateTime EndDate { get; set; }

        // dane z serwisu Yahoo finance
        private List<LoadedMarketData> marketData;


        public Form1()
        {
            InitializeComponent();

            Util = new Utils();
            companyBox.Items.AddRange(InputData.tickerSymbols);
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            UpdateChart();
        }

        private void chart1_Click(object sender, EventArgs e)
        {

        }

        private void trainToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Training == null)
            {
                MessageBox.Show("Pobierz dane");
                return;
            }

            Network = EncogUtility.SimpleFeedForward(14, 100, 0, 1, false);
            EncogUtility.TrainDialog(Network, Training);
        }

        private void getDataToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var input = new InputData(this);
            input.Show();

           
        }

   
        private bool LoadMarketData()
        {
            try
            {
                IMarketLoader loader = new YahooFinanceLoader();
                TickerSymbol ticker = new TickerSymbol(this.companyBox.Text);
                IList<MarketDataType> needed = new List<MarketDataType>();

                // które dane pobrać
                needed.Add(MarketDataType.AdjustedClose);
                needed.Add(MarketDataType.Close);
                needed.Add(MarketDataType.Open);
                needed.Add(MarketDataType.High);
                needed.Add(MarketDataType.Low);

                this.StartDate = this.startDatePicker.Value;
                this.EndDate = this.endDatePicker.Value;

                DateTime from = this.StartDate;
                DateTime to = this.EndDate;
                this.marketData = (List<LoadedMarketData>)loader.Load(ticker, needed, from, to);
                this.marketData.Sort();

                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show("Zły ticker symbol\n" + e.Message, "Błąd");
                return false;
            }
        }

        // rysowanie wykresu po wykonaniu predykcji
        private void UpdateChart()
        {
            double min = double.MaxValue;
            double max = double.MinValue;

            if (LoadMarketData())
            {
               
                chart.Series[0].Points.Clear();
                chart.Series[1].Points.Clear();
                chart.Series[2].Points.Clear();

                for (int i = Util.EvalWindow; i < marketData.Count; i++)
                {

                    LoadedMarketData loadedMarketData = marketData[i];
                    DateTime day = loadedMarketData.When;
                    IDictionary<MarketDataType, double> data = loadedMarketData.Data;

                    int index = chart.Series["Candle"].Points.AddXY(day, data[MarketDataType.High]);
                    chart.Series["Candle"].Points[index].YValues[1] = data[MarketDataType.Low];
                    chart.Series["Candle"].Points[index].YValues[2] = data[MarketDataType.Open];
                    chart.Series["Candle"].Points[index].YValues[3] = data[MarketDataType.Close];

                    double low = data[MarketDataType.Low];
                    double high = data[MarketDataType.High];
                    min = Math.Min(min, low);
                    max = Math.Max(max, high);

                    // Prediction
                    if (Network != null)
                    {
                        var input = Util.CreateData(this.marketData, i);
                        if (input != null)
                        {
                            var output = Network.Compute(input);
                            double d = output[0]; // jeden neuron wyjsciowy

                            if (d < 0.2 || d > 0.8)
                            {

                                if (d < 0.5)
                                {
                                    // red
                                    chart.Series["Bear"].Points.AddXY(day, data[MarketDataType.Low]);
                                }
                                else
                                {
                                    // green;
                                    chart.Series["Bull"].Points.AddXY(day, data[MarketDataType.Low]);
                                }

                            }
                        }
                    }

                }

                double range = max - min;

                chart.ChartAreas[0].AxisY.Minimum = min - (range * 0.1);
                chart.ChartAreas[0].AxisY.Maximum = max + (range * 0.1);
                
            }
        }

        private void startDatePicker_ValueChanged(object sender, EventArgs e)
        {

        }

        private void networkToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void wczytajToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.DefaultExt = ".eg"; // Default file extension
            dlg.Filter = "Encog EG Files (.EG)|*.eg"; // Filter files by extension

            DialogResult result = dlg.ShowDialog();

            if (result == DialogResult.OK)
            {
                FileInfo inf = new FileInfo(dlg.FileName);
                if (inf.Directory != null)
                {

                    var tempn = Encog.Util.NetworkUtil.NetworkUtility.LoadNetwork(inf.Directory.ToString(), dlg.FileName);

                    Network = tempn;
                }



                if (Network == null)
                {
                    MessageBox.Show("This does not appear to be an EG file created for this example.");
                    return;
                }


          
                ParamsHolder xpa = new ParamsHolder(Network.Properties);

                this.Util.EvalWindow = xpa.GetInt("eval", true, 1);
                this.Util.PredictWindow = xpa.GetInt("predict", true, 1);

                this.Util.EvalWindow = xpa.GetInt("eval", true, 1);
                this.Util.PredictWindow = xpa.GetInt("predict", true, 1);
                             
            }
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
        {

        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {

        }

        private void button5_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
          //  DateTime result = DateTime.Today.Subtract(TimeSpan.FromDays(365));
         //   startDatePicker.Value = result;
        }

        private void zapiszToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Network == null)
            {
                MessageBox.Show("You must create a network before you save it.", "Error");
                return;
            }

            SaveFileDialog dlg = new SaveFileDialog();
            dlg.DefaultExt = ".eg"; // Default file extension
            dlg.Filter = "Encog EG Files (.EG)|*.eg"; // Filter files by extension

            DialogResult result = dlg.ShowDialog();

            if (result == DialogResult.OK)
            {


                //If we already have the keys ....we will update them only...
                if (!Network.Properties.ContainsKey("eval"))
                    Network.Properties.Add("eval", this.Util.EvalWindow.ToString());
                /*Update it then */   else
                    Network.Properties["eval"] = Util.EvalWindow.ToString();

                /*Check for predict key */
                if (!Network.Properties.ContainsKey("predict"))
                    Network.Properties.Add("predict", this.Util.PredictWindow.ToString());
                //lets update it if it's already there.
                else
                    Network.Properties["predict"] = Util.PredictWindow.ToString();



                // save
                FileInfo inf = new FileInfo(dlg.FileName);
                if (inf.Directory != null)
                {
                    var tempn = Encog.Util.NetworkUtil.NetworkUtility.SaveNetwork(inf.Directory.ToString(), dlg.FileName,
                                                                                  Network);

                    Network = tempn;
                }

            }
        }



    }
}
